package ru.teleology.cubefs.tests;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;

import java.util.Random;

import org.junit.Test;

import ru.teleology.cubefs.api.exceptions.CubefsException;
import ru.teleology.cubefs.api.models.Manager;
import ru.teleology.cubefs.api.models.Model;

public class CreateRemoveCollectionsTest extends ContainerTestBase {
	
	@Test(expected = CubefsException.class) 
	public void createCollectionWithInvalidName() {
		run(new Ops("createCollectionWithInvalidName") {{
			run(new Op("CreateOp"){{
				container.CreateCollection(2, 0);
			}});
		}});
	}
	
	@Test
	public void createRemove1Collection() {
		run(new Ops("createRemove1Collection") {{
			run(new Op("CreateRemoveOp"){{
				Manager manager = container.GetManager();
				assertNotNull(manager);
				assertEquals(0, manager.GetPageCount());
				
				Model model = container.CreateCollection(2, 1);
				assertEquals(1, model.ModelName());
				assertEquals(1, container.roots().GetSize());
				
				assertEquals(2, manager.GetPageCount());
				
				assertEquals(false, container.Check());
				
				container.RemoveCollection(model);
				assertEquals(0, container.roots().GetSize());
				
				assertEquals(0, manager.GetPageCount());
				
				assertEquals(false, container.Check());
			}});
		}});
	}
	
	@Test 
	public void createRemove100Collections() {
		setChildrenPerNode(5);
		setDump(false);
		final int COUNT = 1000;
		
		final long[] names = new long[COUNT];
		
		Random RND = new Random(0);
		
		for (int c = 0; c < names.length; c++) names[c] = (RND.nextLong() & 0x7fffffffffffffffl) + 1;  
		
		run(new Ops("createRemove"+COUNT+"Collections") {{
			for (int c = 0; c < COUNT; c++) {
				final int cc = c;
				final long name = names[cc];
				
				run(new Op(cc+".CreateOp"){{
					Model model = container.CreateCollection(2, name);
					assertEquals(name, model.ModelName());
					assertEquals(cc + 1, container.roots().GetSize());
					
					Model model1 = container.GetCollectionByName(name);
					assertNotNull(model1);
					assertEquals(name, model1.ModelName());
					
					assertEquals(false, container.Check());
				}});
			}
			
			for (int c = 0; c < COUNT; c++) {
				final int cc = c;
				final long name = names[cc];
				run(new Op(cc+".QueryOp"){{
					Model model = container.GetCollectionByName(name);
					assertNotNull(model);
					assertEquals(name, model.ModelName());
				}});
			}
			
			for (int c = 0; c < COUNT; c++) {
				final int cc = c;
				run(new Op(cc+".RemoveOp"){{
					Model model = container.GetCollectionByName(names[cc]);
					assertNotNull(model);

					container.RemoveCollection(model);
					assertEquals(COUNT - cc - 1, container.roots().GetSize());
					assertEquals(false, container.Check());
				}});
			}
			
			assertEquals(0, container.GetManager().GetPageCount());
			assertEquals(false, container.Check());
		}});
	}
}
